#include "group_service_handler.h"
#include "group_db_wrapper.h"
#include "base/logging.h"
#include "base/format_time.h"
#include "base/json_escape.h"
#include <boost/algorithm/string.hpp>

#include <sstream>

namespace imserver {

int64_t GroupServiceHandler::CreateGroup(const GroupInfo& group_info) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupInfo groupInfo(group_info);
  if (groupInfo.entity_id > 0) {
    if (!GroupDBWrapper::instance().select_tb_group_info(0, groupInfo.type, groupInfo.entity_id,
        groupInfo)) {
      return -1L;
    }
  }
  if (groupInfo.id > 0) {
    LOG_INFO("GroupServiceHandler::CreateGroup --> group already exist. group_id:" << groupInfo.id <<
        " type:" << groupInfo.type << " entity_id:" << groupInfo.entity_id);
    return group_info.id;
  }
  int64_t group_id = GroupIdCreator::instance().createGroupId();
  if (group_id < 0) {
    LOG_ERROR("GroupServiceHandler::CreateGroup --> create group_id failed.");
    return -1L;
  }
  groupInfo.id = group_id;
  groupInfo.create_date = time(NULL);
  if (!GroupDBWrapper::instance().update_tb_group_info(groupInfo)) {
    return -1L;
  }
  LOG_INFO("GroupServiceHandler::CreateGroup --> ok. group_id:" << group_id);
  return group_id;
}

bool GroupServiceHandler::AddGroupTags(int64_t group_id, const std::set<std::string>& tags) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupInfo group_info;
  if (!GroupDBWrapper::instance().select_tb_group_info(group_id, 0, 0, group_info)) {
    return false;
  }
  group_info.tags.insert(tags.begin(), tags.end());
  if (!GroupDBWrapper::instance().update_tb_group_info(group_info)) {
    return false;
  }
  LOG_INFO("GroupServiceHandler::AddGroupTags --> ok. group_id:" << group_id);
  return true;
}

bool GroupServiceHandler::DelGroupTags(int64_t group_id, const std::set<std::string>& tags) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupInfo group_info;
  if (!GroupDBWrapper::instance().select_tb_group_info(group_id, 0, 0, group_info)) {
    return false;
  }
  for (std::set<std::string>::const_iterator it = tags.begin(); it != tags.end(); ++it) {
    group_info.tags.erase(*it);
  }
  if (!GroupDBWrapper::instance().update_tb_group_info(group_info)) {
    return false;
  }
  LOG_INFO("GroupServiceHandler::DelGroupTags --> ok. group_id:" << group_id);
  return true;
}

void GroupServiceHandler::GetGroupInfo(GroupInfo& group_info, int64_t group_id) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupDBWrapper::instance().select_tb_group_info(group_id, 0, 0, group_info);
}

void GroupServiceHandler::GetGroupInfoByEntityId(GroupInfo& group_info, int32_t type, int64_t entity_id) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupDBWrapper::instance().select_tb_group_info(0, type, entity_id, group_info);
}

bool GroupServiceHandler::UpdateGroupInfo(const GroupInfo& group_info) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  if (!GroupDBWrapper::instance().update_tb_group_info(group_info)) {
    return false;
  }
  LOG_INFO("GroupServiceHandler::UpdateGroupInfo --> ok. group_id:" << group_info.id);
  return true;
  
}

void GroupServiceHandler::GetGroupMemberIds(std::set<int64_t>& ret_, int64_t group_id) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupDBWrapper::instance().select_tb_group_member_m(group_id, GroupMemberStatus::GROUP_MEMBER_STATUS_NORMAL, ret_);
}

void GroupServiceHandler::GetJoinedGroupIds(std::set<int64_t>& ret_, int64_t uid) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  GroupDBWrapper::instance().select_tb_group_member_g(uid, GroupMemberStatus::GROUP_MEMBER_STATUS_NORMAL, ret_);
}

bool GroupServiceHandler::JoinInGroup(int64_t group_id, int64_t uid) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  if (!GroupDBWrapper::instance().update_tb_group_member(group_id, uid,
      GroupMemberStatus::GROUP_MEMBER_STATUS_NORMAL)) {
    return false;
  }
  LOG_INFO("GroupServiceHandler::JoinInGroup --> ok. group_id:" << group_id << " uid:" << uid);
  return true;
}

bool GroupServiceHandler::QuitFromGroup(int64_t group_id, int64_t uid) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  //if (!GroupDBWrapper::instance().delete_tb_group_member(group_id, uid)) {
  if (!GroupDBWrapper::instance().update_tb_group_member(group_id, uid,
      GroupMemberStatus::GROUP_MEMBER_STATUS_QUIT)) {
    return false;
  } 
  LOG_INFO("GroupServiceHandler::QuitFromGroup --> ok. group_id:" << group_id << " uid:" << uid);
  return true;
}

bool GroupServiceHandler::SetMemberStatus(int64_t group_id, int64_t uid, int32_t status) {
  base::SimpleMysqlThreadInvoker mysqlInvoker;
  if (!GroupDBWrapper::instance().update_tb_group_member(group_id, uid, status)) {
    return false;
  }
  LOG_INFO("GroupServiceHandler::SetMemberStatus --> ok. group_id:" << group_id << " uid:" << uid <<
      " status:" << status);
  return true;
}

}
